package net.example.model;

import com.oraycn.omcs.utils.SerializeUtils;
import com.oraycn.esbasic.helpers.StringHelper;

import net.example.model.event.UserHeadImageChangedEvent;

import java.io.IOException;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import de.greenrobot.event.EventBus;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class GGUser {
    //仅客户端显示备注使用
    private String CommentName;
    private String CommentNames;
    private Date CreateTime;
    private String Friends;
    private byte[] HeadImageData;
    private int HeadImageIndex;
    private String OrgID ="";
    private String PasswordMD5;
    private String Signature;
    private UserStatus UserStatus;
    private int Version;
    private String Groups;
    private LastWordsRecord lastWordsRecord;
    private String Name;
    private String UserID;
    private HashMap<String, ArrayList<String>> friendMap;
    public boolean statusChanged;
    public boolean isNewMsg;

    private int HeadImageDataLen;

    public String getLoginID() {
        return "2#" + getUserID();
    }


    public void setHeadImageDataLen(int headImageDataLen) {
        HeadImageDataLen = headImageDataLen;
    }

    public String getCommentName() {
        if(StringHelper.isNullOrEmpty(CommentName))
        {
            return Name;
        }
        return CommentName;
    }

    public void setCommentName(String commentName) {
        CommentName = commentName;
    }

    public String getCommentNames() {
        return CommentNames;
    }

    public void setCommentNames(String commentNames) {
        CommentNames = commentNames;
    }

    public Date getCreateTime() {
        return CreateTime;
    }

    public void setCreateTime(Date createTime) {
        CreateTime = createTime;
    }

    public byte[] getHeadImageData() {
        return HeadImageData;
    }

    public void setHeadImageData(byte[] headImageData) {
        HeadImageData = headImageData;
    }

    public String getOrgID() {
        return OrgID;
    }

    public void setOrgID(String orgID) {
        OrgID = orgID;
    }

    public String getPasswordMD5() {
        return PasswordMD5;
    }

    public void setPasswordMD5(String passwordMD5) {
        PasswordMD5 = passwordMD5;
    }

    public int getVersion() {
        return Version;
    }

    public void setVersion(int version) {
        Version = version;
    }

    public LastWordsRecord getLastWordsRecord() {
        return lastWordsRecord;
    }

    public void setLastWordsRecord(LastWordsRecord lastWordsRecord) {
        this.lastWordsRecord = lastWordsRecord;
    }

    private HashMap<String, String> commandNameDictionary = null;

    public HashMap<String, String> getCommandNameDictionary(){
        if (this.commandNameDictionary != null)
        {
            return this.commandNameDictionary;
        }
        this.commandNameDictionary = new HashMap<String, String>();
        if (!StringHelper.isNullOrEmpty(this.CommentNames))
        {
            String[] users=this.CommentNames.split(";");
            for (String commentName:users) {
                String[] commentNameArray= commentName.split(":");
                this.commandNameDictionary.put(commentNameArray[0],commentNameArray[1]);
            }
        }
        return this.commandNameDictionary;
    }

    /// <summary>
    /// 增加或更新好友备注。如果commentName为null或String.Empty，则表示取消备注。
    /// </summary>
    public void changeUnitCommentName(String unitID, String commentName)
    {
        this.commandNameDictionary=this.getCommandNameDictionary();
        this.commandNameDictionary.remove(unitID);
        if (!StringHelper.isNullOrEmpty(commentName))
        {
            this.commandNameDictionary.put(unitID, commentName);
        }
        String commentNames="";
        for ( Map.Entry<String, String> entry : this.commandNameDictionary.entrySet()) {
            commentNames+=entry.getKey()+":"+entry.getValue()+";";
        }
        if(commentNames.length()>0)
        {
            commentNames=commentNames.substring(0,commentNames.length()-1);
        }
        this.CommentNames=commentNames;
    }

    public String getUnitCommentName(String unitID)
    {
        this.commandNameDictionary=this.getCommandNameDictionary();
        if (this.commandNameDictionary.containsKey(unitID))
        {
            return this.commandNameDictionary.get(unitID);
        }
        return null;
    }

    public String getFriends() {
        return Friends;
    }

    public List<String> getFriendList(){
        if(StringHelper.isNullOrEmpty(Friends))
        {
            return new ArrayList<String>();
        }
        List<String> friendList=new ArrayList<String>();
        HashMap<String,ArrayList<String>> map=this.getFriendMap();
        for (Map.Entry<String, ArrayList<String>> pair :map.entrySet()) {
            if(!pair.getKey().equals("黑名单")&&pair.getValue().size()>0)
            {
                friendList.addAll(pair.getValue());
            }
        }
        return friendList  ;
    }

    public void setFriends(String friends) {
        Friends = friends;
    }

    private void setFriendMap()
    {
        friendMap=new HashMap<String,ArrayList<String>>();
        if (StringHelper.isNullOrEmpty(this.Friends)) {
            this.Friends = "我的好友";
            this.Friends += ";黑名单:";
        }
        String[] catalogs = this.Friends.split(";");
        for (String catalog : catalogs) {
            if (StringHelper.isNullOrEmpty(catalog)) {
                break;
            }
            String[] ary = catalog.split(":");
            String catalogName = ary[0];
            ArrayList<String> friendList = null;
            if (ary.length < 2) {
                friendList = new ArrayList<String>();
            } else {
                friendList = new ArrayList<String>(Arrays.asList(ary[1].split(",")));
            }
            if (friendList.size() == 1) {
                friendList.remove("");
            }
            friendMap.put(catalogName, friendList);
        }
        if (!friendMap.containsKey("黑名单")) {
            friendMap.put("黑名单", new ArrayList<String>());
            this.Friends += ";黑名单:";
        }
    }

    public HashMap<String,ArrayList<String>> getFriendMap() {
        if(friendMap==null)
        {
            this.setFriendMap();
        }
        return (HashMap<String,ArrayList<String>>)friendMap.clone();
    }

    public Boolean isFriend(String friendID) {
        HashMap<String, ArrayList<String>> friendMap = getFriendMap();
        for (ArrayList<String> firendIDs : friendMap.values()
        ) {
            if (firendIDs.contains(friendID)) {
                return true;
            }
        }
        return false;
    }

    //根据好友ID，获取好友在我的好友分组列表名称 （好友不存在或者未在好友列表返回 “”）
    public String getCatalogNameByFriend(String friendID)
    {
        String catalogName="";
        if(StringHelper.isNullOrEmpty(friendID))
        {
            return catalogName;
        }
        HashMap<String,ArrayList<String>> friendMap=this.getFriendMap();
        for (Map.Entry<String, ArrayList<String>> kvp :friendMap.entrySet()) {
            if(kvp.getValue().contains(friendID))
            {
                return kvp.getKey();
            }
        }
        return catalogName;
    }

    //获取好友分组列表
    public List<String> getCatalogNameList()
    {
        HashMap<String,ArrayList<String>> friendMap=this.getFriendMap();
        List<String> list= new ArrayList(friendMap.keySet()) ;
        list.remove("黑名单");
        list.remove("我的好友");
        list.add(0,"我的好友");
        return list;
    }

    public void AddFriendCatalog(String catalogName)
    {
        List<String> catalogNameList=this.getCatalogNameList();
        if(catalogNameList.contains(catalogName))
        {
            return;
        }
        this.Friends+=String.format(";%s:",catalogName);
        this.setFriendMap();
    }

    public void moveFriend(String friendID, String oldCatalog, String newCatalog)
    {
        List<String> catalogNameList=this.getCatalogNameList();
        if (!catalogNameList.contains(oldCatalog) || !catalogNameList.contains(newCatalog))
        {
            return;
        }
        HashMap<String,ArrayList<String>> map= getFriendMap();

        map.get(oldCatalog).remove(friendID);
        if (!map.get(newCatalog).contains(friendID))
        {
            map.get(newCatalog).add(friendID);
        }
        this.Friends = this.getFriendsVal(map);
        this.setFriendMap();
    }

    private String getFriendsVal(HashMap<String,ArrayList<String>> map)
    {
        StringBuilder sb = new StringBuilder();
        int count = 0;
        for (Map.Entry<String, ArrayList<String>> pair : map.entrySet())
        {
            if (count > 0)
            {
                sb.append(";");
            }
            String ff = StringHelper.ContactString(pair.getValue(), ",");
            sb.append(String.format("%s:%s", pair.getKey(), ff));
            ++count;
        }
        return sb.toString();
    }

    public String getGroups() {
        return Groups;
    }

    public void setGroups(String groups) {
        Groups = groups;
    }

    public List<String> getGroupList()
    {
        String[] groupAry = Groups.split(",");
        return new ArrayList<>(Arrays.asList(groupAry));
    }

    public void removeGroup(String groupID)
    {
        if(StringHelper.isNullOrEmpty(groupID))
        {
            return;
        }
        List<String> groupList = this.getGroupList();
        groupList.remove(groupID);
        this.Groups=StringHelper.ContactString(groupList,",");
    }

    public void addGroup(String groupID)
    {
        if(StringHelper.isNullOrEmpty(groupID))
        {
            return;
        }
        List<String> groupList = this.getGroupList();
        if(!groupList.contains(groupID)){
            groupList.add(groupID);
        }
        this.Groups=StringHelper.ContactString(groupList,",");
    }

    public void updateHeadImage(int headImageIndex, byte[] headImageData) {

        if (headImageData != null && headImageData.length > 0) {
            //若是自己修改了自己的自定义头像，直接从服务端拿最新的数据（主要是为了拿到圆形头像）
            this.setHeadImageIndex(-1);
            setHeadImageData(headImageData);
            setHeadImageDataLen(headImageData.length);

        } else {
            this.setHeadImageIndex(headImageIndex);
            this.setHeadImageData(null);
            this.setHeadImageDataLen(0);
        }
        EventBus.getDefault().post(new UserHeadImageChangedEvent(UserID, HeadImageIndex, HeadImageData));
    }

    //是否在自己的黑名单中
    public boolean isInMyBlackList(String destUserID)
    {
       return this.getCatalogNameByFriend(destUserID).equals("黑名单");
    }

    public int getHeadImageIndex() {
        return HeadImageIndex;
    }

    public void setHeadImageIndex(int headImageIndex) {
        HeadImageIndex = headImageIndex;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    public String getSignature() {
        return Signature;
    }

    public void setSignature(String signature) {
        Signature = signature;
    }

    public String getUserID() {
        return UserID;
    }

    public void setUserID(String userID) {
        UserID = userID;
    }

    public UserStatus getUserStatus() {
        return UserStatus;
    }

    public void setUserStatus(UserStatus userStatus) {
        UserStatus = userStatus;
    }

    public String Phone;

    public UserState UserState;

    public void deserialize(byte[] bytes) throws IOException {
        ByteBuf buffer = Unpooled.wrappedBuffer(bytes).order(ByteOrder.LITTLE_ENDIAN);
        this.deserialize(buffer);
    }

    private void deserialize(ByteBuf buffer) throws IOException {
        buffer.readInt();
        this.CommentName = SerializeUtils.readStrIntLen(buffer);
        this.CommentNames = SerializeUtils.readStrIntLen(buffer);
        this.CreateTime = new Date(buffer.readLong());
        this.Friends = SerializeUtils.readStrIntLen(buffer);
        this.setFriendMap();
        this.Groups = SerializeUtils.readStrIntLen(buffer);
        this.HeadImageDataLen = buffer.readInt();

        if (this.HeadImageDataLen > 0) {
            this.HeadImageData = new byte[this.HeadImageDataLen];
            buffer.readBytes(HeadImageData);
        }
        this.HeadImageIndex = buffer.readInt();
        this.lastWordsRecord = new LastWordsRecord();
        this.lastWordsRecord.deserialize(buffer);

        this.Name = SerializeUtils.readStrIntLen(buffer);
        this.OrgID = SerializeUtils.readStrIntLen(buffer);
        this.PasswordMD5 = SerializeUtils.readStrIntLen(buffer);
        this.Signature = SerializeUtils.readStrIntLen(buffer);
        this.UserID = SerializeUtils.readStrIntLen(buffer);
        this.UserState= net.example.model.UserState.getUserStateByCode(buffer.readInt());
        this.UserStatus = net.example.model.UserStatus.getUserStatusByCode(buffer.readInt());
        this.Version = buffer.readInt();
    }

    public static ArrayList<GGUser> deserializeUserList(byte[] bytes) throws IOException {
        ByteBuf buffer = Unpooled.wrappedBuffer(bytes).order(ByteOrder.LITTLE_ENDIAN);
        ArrayList<GGUser> list = new ArrayList<GGUser>();
        int userCount = buffer.readInt();

        for (int i = 0; i < userCount; i++) {
            GGUser user = new GGUser();
            user.deserialize(buffer);
            list.add(user);
        }
        return list;
    }
}
